package com.fowo.api.syncAmazon.core.sync;

import com.amazon.spapi.model.reports.CreateReportSpecification;
import com.amazon.spapi.model.reports.Report;
import com.amazon.spapi.model.reports.ReportDocument;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.entity.TmpFbaInventory;
import com.fowo.api.syncAmazon.core.AbstractAmazonSyncData;
import com.fowo.api.syncAmazon.core.ReportApiType;
import com.fowo.api.syncAmazon.entity.ApiDefine;
import com.fowo.api.syncAmazon.entity.ApiRequestLog;
import com.fowo.api.syncAmazon.entity.TmpInventoryStatusReport;
import com.fowo.api.syncAmazon.mapper.AmazonTmpMapper;
import com.fowo.api.syncAmazon.service.TmpInventoryStatusReportService;
import com.fowo.api.syncAmazon.service.impl.TmpInventoryStatusReportServiceImpl;
import com.fowo.api.syncAmazon.util.GeneralUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;

/**
 * @fileName: ManageFBAInventoryStatusSync
 * @Description: 代码目的，作用，如何工作
 * @Author: yyf
 * @Date: 2024/2/28 0028 13:30
 */
@Component
public class ManageFBAInventoryStatusSync extends AbstractAmazonSyncData {
    @Resource
    private TmpInventoryStatusReportServiceImpl tmpInventoryStatusReportService;

    private ApiDefine apiDefine = ApiDefine.builder()
            .apiCode("manage_FBA_inventory_status")
            .initdate(1)
            .timeInterval(1)
            .timeIntervalType("day").build();

    @Override
    protected ApiDefine setApiDefine() {
        return apiDefine;
    }

    @Override
    protected void requestData() throws Exception {
        // 获取卖家账号信息
        String platform = "Amazon";
        this.getAuthority(platform);
        // 查询该账号下所有店铺
        LambdaQueryWrapper<ShopInfo> shopInfosWrapper = new LambdaQueryWrapper<>();
        shopInfosWrapper.eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01");
        List<ShopInfo> shopInfoList = shopInfoServiceImpl.list(shopInfosWrapper);

        // 清空临时表
        tmpInventoryStatusReportService.getBaseMapper().cleanAll();

        //请求报告
        for (ShopInfo shopInfo : shopInfoList) {
            //创建报告 -查询参数
            List<String> marketplaceIds = Arrays.asList(shopInfo.getMarketplaceId().split(","));
            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType(ReportApiType.GET_FBA_INVENTORY_PLANNING_DATA);
//            ReportOptions reportOptions = new ReportOptions();
//            body.setReportOptions(reportOptions);
            body.setMarketplaceIds(marketplaceIds);
            // 获取拉取的时间区间
//            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(this.getStartTime()));
//            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(this.getEndTime()));


            // 第一步 创建报告
            final String reportId = retryCreateReport(shopInfo, body);
            // 第二步 检验报告是否完成
            Report report = retryCheckReport(shopInfo, reportId);
            // 第三步 获取报告连接
            ReportDocument reportDocument = getReportDocument(shopInfo,report.getReportDocumentId());
            System.out.println(reportDocument.getUrl());

            if (reportDocument != null) {
                String compressionAlgorithm = reportDocument.getCompressionAlgorithm() != null ? reportDocument.getCompressionAlgorithm().getValue() : null;
                BufferedReader reader = this.getAndUnzipReport(reportDocument.getUrl(), compressionAlgorithm);
                try {
                    download(reader, shopInfo);
                }catch (Exception ex){
                    apiRequestLog.setErrorMessage("解析与下载报告出现异常："+ex);
                    apiRequestLog.setStatus(ApiRequestLog.FAIL);
                    super.apiRequestLogService.getBaseMapper().updateById(apiRequestLog);
                }finally {
                    reader.close();
                }
            }
        }
    }

    @Override
    protected <T> void download(T param, ShopInfo shop) throws IOException, IllegalArgumentException {
        BufferedReader reader = null;
        if (param instanceof BufferedReader){
            try {
                reader = (BufferedReader)param;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }

        int lineNumber = 0;
        String line = null;
        Map<String,Integer> titleList = new HashMap<>();
        List<TmpInventoryStatusReport> list = new ArrayList<>();

        while ((line = reader.readLine()) != null) {
            String[] info = line.split("\t");
            int length = info.length;
            if (lineNumber == 0) {
                for (int i = 0; i < length; i++) {
                    titleList.put(info[i],i);
                }
            } else {
                Map<String, Object> fields = this.getFieldsFromInfo(info, titleList);
                TmpInventoryStatusReport tmp = new TmpInventoryStatusReport();

                tmp.setSid(shop.getId());
                tmp.setSnapshotDate(GeneralUtil.getDate(fields.get("snapshot-date")));
                tmp.setSku(fields.get("sku").toString());
                tmp.setFnsku(fields.get("fnsku").toString());
                tmp.setAsin(fields.get("asin").toString());
                tmp.setProductName(fields.get("product-name").toString());
                tmp.setConditionStr(fields.get("condition").toString());
                tmp.setAvailable(GeneralUtil.getIntegerValue(fields.get("available")));
                tmp.setReservedQuantity(GeneralUtil.getIntegerValue(fields.get("reserved-quantity")));
                tmp.setInvAge0To90Days(GeneralUtil.getIntegerValue(fields.get("inv-age-0-to-90-days")));
                tmp.setInvAge91To180Days(GeneralUtil.getIntegerValue(fields.get("inv-age-91-to-180-days")));
                tmp.setInvAge181To270Days(GeneralUtil.getIntegerValue(fields.get("inv-age-181-to-270-days")));
                tmp.setInvAge271To365Days(GeneralUtil.getIntegerValue(fields.get("inv-age-271-to-365-days")));
                tmp.setInvAge365PlusDays(GeneralUtil.getIntegerValue(fields.get("inv-age-365-plus-days")));
                tmp.setCurrency(fields.get("currency").toString());
                tmp.setUnitsShippedT7(GeneralUtil.getIntegerValue(fields.get("units-shipped-t7")));
                tmp.setUnitsShippedT30(GeneralUtil.getIntegerValue(fields.get("units-shipped-t30")));
                tmp.setUnitsShippedT60(GeneralUtil.getIntegerValue(fields.get("units-shipped-t60")));
                tmp.setUnitsShippedT90(GeneralUtil.getIntegerValue(fields.get("units-shipped-t90")));
                tmp.setAlert(fields.get("alert").toString());
                tmp.setYourPrice(GeneralUtil.getBigDecimal(fields.get("your-price").toString()));
                tmp.setSalesPrice(GeneralUtil.getBigDecimal(fields.get("sales-price").toString()));
                tmp.setLowestPriceNewPlusShipping(GeneralUtil.getBigDecimal(fields.get("lowest-price-new-plus-shipping").toString()));
                tmp.setLowestPriceUsed(GeneralUtil.getBigDecimal(fields.get("lowest-price-used").toString()));
                tmp.setRecommendedAction(fields.get("recommended-action").toString());
                tmp.setHealthyInventoryLevel(fields.get("healthy-inventory-level").toString());
                tmp.setRecommendedSalesPrice(GeneralUtil.getBigDecimal(fields.get("recommended-sales-price").toString()));
                tmp.setRecommendedSaleDurationDays(GeneralUtil.getIntegerValue(fields.get("recommended-sale-duration-days")));
                tmp.setRecommendedRemovalQuantity(GeneralUtil.getIntegerValue(fields.get("recommended-removal-quantity")));
                tmp.setEstimatedCostSavingsOfRecommendedActions(GeneralUtil.getBigDecimal(fields.get("estimated-cost-savings-of-recommended-actions").toString()));
                tmp.setSellThrough(GeneralUtil.getBigDecimal(fields.get("sell-through").toString()));
                tmp.setItemVolume(GeneralUtil.getBigDecimal(fields.get("item-volume").toString()));

                tmp.setVolumeUnitMeasurement(fields.get("volume-unit-measurement").toString());
                tmp.setStorageType(fields.get("storage-type").toString());
                tmp.setStorageVolume(GeneralUtil.getBigDecimal(fields.get("storage-volume").toString()));
                tmp.setMarketplace(fields.get("marketplace").toString());
                tmp.setProductGroup(fields.get("product-group").toString());
                tmp.setSalesRank(GeneralUtil.getIntegerValue(fields.get("sales-rank")));
                tmp.setDaysOfSupply(GeneralUtil.getIntegerValue(fields.get("days-of-supply")));
                tmp.setEstimatedExcessQuantity(GeneralUtil.getIntegerValue(fields.get("estimated-excess-quantity")));
                tmp.setWeeksOfCoverT30(GeneralUtil.getBigDecimalValue(fields.get("weeks-of-cover-t30").toString()));
                tmp.setWeeksOfCoverT90(GeneralUtil.getBigDecimal(fields.get("weeks-of-cover-t90").toString()));
                tmp.setFeaturedofferPrice(GeneralUtil.getBigDecimal(fields.get("featuredoffer-price").toString()));
                tmp.setSalesShippedLast7Days(GeneralUtil.getIntegerValue(fields.get("sales-shipped-last-7-days")));
                tmp.setSalesShippedLast30Days(GeneralUtil.getIntegerValue(fields.get("sales-shipped-last-30-days")));
                tmp.setSalesShippedLast60Days(GeneralUtil.getIntegerValue(fields.get("sales-shipped-last-60-days")));
                tmp.setSalesShippedLast90Days(GeneralUtil.getIntegerValue(fields.get("sales-shipped-last-90-days")));
                tmp.setInvAge0To30Days(GeneralUtil.getIntegerValue(fields.get("inv-age-0-to-30-days")));
                tmp.setInvAge31To60Days(GeneralUtil.getIntegerValue(fields.get("inv-age-31-to-60-days")));
                tmp.setInvAge61To90Days(GeneralUtil.getIntegerValue(fields.get("inv-age-61-to-90-days")));
                tmp.setInvAge91To180Days(GeneralUtil.getIntegerValue(fields.get("inv-age-91-to-180-days")));
                tmp.setInvAge331To365Days(GeneralUtil.getIntegerValue(fields.get("inv-age-331-to-365-days")));
                tmp.setEstimatedStorageCostNextMonth(GeneralUtil.getBigDecimal(fields.get("estimated-storage-cost-next-month").toString()));
                tmp.setInboundQuantity(GeneralUtil.getIntegerValue(fields.get("inbound-quantity")));
                tmp.setInboundWorking(GeneralUtil.getIntegerValue(fields.get("inbound-working")));
                tmp.setInboundShipped(GeneralUtil.getIntegerValue(fields.get("inbound-shipped")));
                tmp.setInboundReceived(GeneralUtil.getIntegerValue(fields.get("inbound-received")));
                tmp.setNoSaleLast6Months(GeneralUtil.getIntegerValue(fields.get("no-sale-last-6-months")));
                tmp.setReservedQuantity(GeneralUtil.getIntegerValue(fields.get("reserved-quantity")));
                tmp.setUnfulfillableQuantity(GeneralUtil.getIntegerValue(fields.get("unfulfillable-quantity")));
                tmp.setQuantityToBeChargedAis301330Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-181-210-days")));
                tmp.setEstimatedAis181210Days(GeneralUtil.getBigDecimal(fields.get("estimated-ais-181-210-days").toString()));
                tmp.setQuantityToBeChargedAis301330Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-211-240-days")));
                tmp.setEstimatedAis211240Days(GeneralUtil.getBigDecimal(fields.get("estimated-ais-211-240-days").toString()));
                tmp.setQuantityToBeChargedAis301330Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-241-270-days")));
                tmp.setEstimatedAis241270Days(GeneralUtil.getBigDecimal(fields.get("estimated-ais-241-270-days").toString()));
                tmp.setQuantityToBeChargedAis301330Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-271-300-days")));
                tmp.setEstimatedAis271300Days(GeneralUtil.getBigDecimal(fields.get("estimated-ais-271-300-days").toString()));
                tmp.setQuantityToBeChargedAis301330Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-301-330-days")));
                tmp.setEstimatedAis301330Days(GeneralUtil.getBigDecimal(fields.get("estimated-301-330-days").toString()));
                tmp.setQuantityToBeChargedAis331365Days(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-331-365-days")));
                tmp.setEstimatedAis331365Days(GeneralUtil.getBigDecimal(fields.get("estimated-ais-331-365-days").toString()));
                tmp.setQuantityToBeChargedAis365PlusDays(GeneralUtil.getIntegerValue(fields.get("quantity-to-be-charged-ais-365-plus-days")));
                tmp.setEstimatedAis365PlusDays(GeneralUtil.getBigDecimal(fields.get("estimated-ais-365-plus-days").toString()));
                tmp.setHistoricalDaysOfSupply(GeneralUtil.getIntegerValue(fields.get("historical-days-of-supply")));
                tmp.setFbaMinimumInventoryLevel(GeneralUtil.getIntegerValue(fields.get("fba-minimum-inventory-level")));
                tmp.setFbaInventoryLevelHealthStatus(fields.get("fba-inventory-level-health-status").toString());
                tmp.setRecommendedShipInQuantity(GeneralUtil.getIntegerValue(fields.get("Recommended ship-in quantity")));
                tmp.setRecommendedShipInDate(GeneralUtil.getDate(fields.get("Recommended ship-in date")));

                list.add(tmp);
            }
            lineNumber++;
        }
        // 写入同步数据量
        Integer dataVolume = apiRequestLog.getDataVolume() == null ? 0 : apiRequestLog.getDataVolume();
        apiRequestLog.setDataVolume(dataVolume+list.size());

        tmpInventoryStatusReportService.saveBatch(list);
    }

    @Override
    protected void updateOrInsertData() {
        tmpInventoryStatusReportService.getBaseMapper().insertOrUpdate();
    }
}
